package com.rzt.cft.api.fiter;

import cn.hutool.json.JSONUtil;
import com.rzt.cft.constant.ServiceStatus;
import com.rzt.cft.dto.ResponseData;
import com.rzt.cft.utils.CustomUtil;
import com.rzt.cft.utils.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @Description: 拦截器
 * @Author: ZZ
 * @Date: 2018-08-09 16:16
 */
@Slf4j
@Component
public class ApiSecurityInterceptor extends HandlerInterceptorAdapter {

    public static final String HEADER_TOKEN = "Authorization";

    /**
     * API-当前会话中的用户id
     */
    public static String API_CURRENT_USER_ID = "user_id";

    /**
     * 在DispatcherServlet之前执行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime ldt = LocalDateTime.parse("2020-04-05 00:00:00",df);
        if (ldt.isBefore(LocalDateTime.now())) {
            return customResponse(response, ServiceStatus.SERVICE_EXPIRED);
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        String token = request.getHeader(HEADER_TOKEN);
        // 校验token
        Boolean result = verifyToken(token, request);
        // 是否需要验证
        CustomAuthorize custom = handlerMethod.getMethodAnnotation(CustomAuthorize.class);
        if (CustomUtil.isTrue(custom, CustomAuthorize::skip)) {
            return true;
        }

        if (!result) {
            return customResponse(response, ServiceStatus.TOKEN_INVALID);
        }
        return true;
    }

    /**
     * 校验token
     *
     * @param token
     * @param request
     * @return
     */
    private Boolean verifyToken(String token, HttpServletRequest request) {
        if (StringUtils.isBlank(token)) {
            return false;
        }
        String userId = JwtUtil.verifyTokenAndGetUserId(token);
        if (StringUtils.isBlank(userId)) {
            return false;
        }
        request.setAttribute(API_CURRENT_USER_ID, userId);
        return true;
    }

    /**
     * 自定义响应
     *
     * @param response
     * @param serviceStatus
     */
    private boolean customResponse(HttpServletResponse response, ServiceStatus serviceStatus) throws IOException {
        ResponseData<String> result = new ResponseData<>(serviceStatus);
        response.setStatus(HttpServletResponse.SC_OK);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println(JSONUtil.toJsonStr(result));
        return false;
    }

}
